package com.finance.rule.service;

import com.finance.base.enums.StateEnum;
import com.finance.rule.bean.pojo.MasterRule;
import com.finance.rule.bean.pojo.NewPieceRule;
import com.finance.rule.bean.pojo.NewRuleList;
import com.finance.rule.bean.pojo.NewWeightRule;
import com.finance.rule.dao.MasterRuleMapper;
import com.finance.rule.dao.NewRuleMapper;
import com.finance.system.bean.pojo.Carrier;
import com.finance.system.bean.pojo.Region;
import com.finance.system.bean.pojo.Supplier;
import com.finance.system.bean.pojo.User;
import com.finance.system.dao.CarrierMapper;
import com.finance.system.dao.RegionCodeMapper;
import com.finance.system.dao.SupplierMapper;
import com.finance.util.pager.Pagination;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by gly on 2017/8/5.
 */
@Service
public class NewRuleService implements INewRuleService {
    @Autowired
    private NewRuleMapper newRuleMapper;
    @Autowired
    private RegionCodeMapper regionCodeMapper;
    @Autowired
    private SupplierMapper supplierMapper;
    @Autowired
    private CarrierMapper carrierMapper;
    @Resource
    private ISettlementRegionService settlementRegionService;
    @Resource
    private IMasterRuleService masterRuleService;
    @Autowired
    private MasterRuleMapper masterRuleMapper;

    @Override
    public List<NewRuleList> getRulesListPage(String province, String city, String supplierCode, String carrierCode, Pagination pagination) {
        NewRuleList newRuleList = new NewRuleList();
        newRuleList.setToProvince(Integer.parseInt(province));
        newRuleList.setToCity(Integer.parseInt(city));
        newRuleList.setSupplierCode(supplierCode);
        newRuleList.setCarrierCode(carrierCode);
        newRuleList.setStartOffset((pagination.getPage() - 1) * pagination.getRows());
        newRuleList.setEndOffset(pagination.getRows());
        return this.newRuleMapper.getNewsRuleListPage(newRuleList);
    }

    @Override
    public Pagination getRulePage(String province, String city, String supplierCode, String carrierCode, Pagination pagination) {
        NewRuleList newRuleList = new NewRuleList();
        newRuleList.setToProvince(Integer.parseInt(province));
        newRuleList.setToCity(Integer.parseInt(city));
        newRuleList.setSupplierCode(supplierCode);
        newRuleList.setCarrierCode(carrierCode);
        int count = this.newRuleMapper.countRuleList(newRuleList);
        pagination.setTotal(count);
        String totalPage = String.valueOf(Math.ceil(count % pagination.getRows() != 0 ? count / pagination.getRows() + 1 : count / pagination.getRows()));
        pagination.setTotalPage(Integer.parseInt(totalPage.substring(0, totalPage.indexOf('.'))));
        return pagination;
    }

    @Override @Transactional
    public long saveNewWeightRule(List<Map<String,Object>> ruleList, User user){
        long version = System.currentTimeMillis();
        newRuleMapper.bankupWeightRuleAll(version);
        masterRuleService.deleteMasterRule(1);
        newRuleMapper.deleteWeightRulesAll();
        for (Map<String,Object> rule : ruleList){
            MasterRule masterRule = (MasterRule)rule.get("masterRule");
            List<NewWeightRule> newWeightRuleList = (List<NewWeightRule>)rule.get("newWeightRuleList");
            if (null != masterRule && null != newWeightRuleList && newWeightRuleList.size()>0){
                this.saveNewWeight(masterRule,newWeightRuleList,user);
            }
        }
        return version;
    }

    @Override @Transactional
    public void saveNewWeightRule(MasterRule masterRule, List<NewWeightRule> newWeightRuleList, User user) {
        String masterRuleIdExist = String.valueOf(masterRuleService.masterRuleIsExist(masterRule.getSupplierCode(),masterRule.getCarrierCode(),masterRule.getToProvince()));
        if(StringUtils.isNotBlank(masterRuleIdExist)){
            masterRuleService.deleteMasterRule(masterRule.getSupplierCode(),masterRule.getCarrierCode(),masterRule.getToProvince());
            long version = System.currentTimeMillis();
            newRuleMapper.bankupWeightRule(masterRuleIdExist,version);
            newRuleMapper.deleteWeightRules(masterRuleIdExist);
        }
        this.saveNewWeight(masterRule,newWeightRuleList,user);
    }

    private void saveNewWeight(MasterRule masterRule, List<NewWeightRule> newWeightRuleList, User user){
        masterRule.setCreateUid(user.getId());
        masterRule.setState(StateEnum.Valid.getState());
        Long masterRuleId = masterRuleService.add(masterRule);
        Iterator<NewWeightRule> iterator = newWeightRuleList.iterator();
        while (iterator.hasNext()) {
            NewWeightRule newWeightRule = iterator.next();
            String level = newWeightRule.getRegionId();
            if (StringUtils.isNotBlank(level)){
                StringBuilder ids = new StringBuilder();
                String toProvince = String.valueOf(newWeightRule.getToProvince());
                String code = toProvince.substring(0, 2);
                List<String> idList = settlementRegionService.getIds(level, code);
                Iterator<String> it = idList.iterator();
                while (it.hasNext()) {
                    ids.append(it.next()).append(",");
                }
                if (ids.length()>0){
                    ids.deleteCharAt(ids.length() - 1);
                    newWeightRule.setRegionId(ids.toString());
                }
            }
            newWeightRule.setMasterRuleId(masterRuleId);
            newWeightRule.setCreateUid(user.getId());
            newWeightRule.setState(StateEnum.Valid.getState());
            newRuleMapper.addWeight(newWeightRule);
        }
    }

    @Override @Transactional
    public long saveNewPieceRule(List<Map<String,Object>> ruleList,User user) {
        long version = System.currentTimeMillis();
        newRuleMapper.bankupPieceRuleALL(version);
        masterRuleService.deleteMasterRule(0);
        newRuleMapper.deletePieceRulesAll();
        for (Map<String, Object> rule : ruleList) {
            MasterRule masterRule = (MasterRule) rule.get("masterRule");
            List<NewPieceRule> newPieceRuleList = (List<NewPieceRule>) rule.get("newPieceRuleList");
            if (null != masterRule && null != newPieceRuleList && newPieceRuleList.size() > 0) {
                this.saveNewPiece(masterRule,newPieceRuleList,user);
            }
        }
        return version;
    }

    @Override @Transactional
    public void saveNewPieceRule(MasterRule masterRule, List<NewPieceRule> newPieceRuleList, User user) {
        String masterRuleIdExist = String.valueOf(masterRuleService.masterRuleIsExist(masterRule.getSupplierCode(),masterRule.getCarrierCode(),masterRule.getToProvince()));
        if(StringUtils.isNotBlank(masterRuleIdExist)){
            masterRuleService.deleteMasterRule(masterRule.getSupplierCode(),masterRule.getCarrierCode(),masterRule.getToProvince());
            long version = System.currentTimeMillis();
            newRuleMapper.bankupPieceRule(masterRuleIdExist,version);
            newRuleMapper.deletePieceRules(masterRuleIdExist);
        }
        this.saveNewPiece(masterRule,newPieceRuleList,user);
    }

    private void saveNewPiece(MasterRule masterRule, List<NewPieceRule> newPieceRuleList, User user){
        masterRule.setCreateUid(user.getId());
        masterRule.setState(StateEnum.Valid.getState());
        Long masterRuleId = masterRuleService.add(masterRule);
        Iterator<NewPieceRule> iterator = newPieceRuleList.iterator();
        while (iterator.hasNext()) {
            NewPieceRule newPieceRule = iterator.next();
            String level = newPieceRule.getRegionId();
            if (StringUtils.isNotBlank(level)) {
                String toProvince = String.valueOf(newPieceRule.getToProvince());
                String code = toProvince.substring(0, 2);
                StringBuilder ids = new StringBuilder();
                List<String> idList = settlementRegionService.getIds(level, code);
                Iterator<String> it = idList.iterator();
                while (it.hasNext()) {
                    ids.append(it.next()).append(",");
                }
                if (ids.length()>0){
                    ids.deleteCharAt(ids.length() - 1);
                    newPieceRule.setRegionId(ids.toString());
                }
            }
            newPieceRule.setMasterRuleId(masterRuleId);
            newPieceRule.setCreateUid(user.getId());
            newPieceRule.setState(StateEnum.Valid.getState());
            newRuleMapper.addPiece(newPieceRule);
        }
    }

    @Override
    public MasterRule getMasterRule(String ruleId) {
        return masterRuleMapper.getMasterRules(ruleId);
    }

    @Override
    public List<NewPieceRule> getNewPieceRules(String ruleId) {
        return newRuleMapper.getNewPieceRules(ruleId);
    }

    @Override
    public List<NewWeightRule> getNewWeightRules(String ruleId) {
        return newRuleMapper.getNewWeightRules(ruleId);
    }

    @Override
    public List<Region> getFatherRegionList() {
        return regionCodeMapper.getProvinceList();
    }

    @Override
    public List<Supplier> getSupplierList() {
        return supplierMapper.listAll();
    }

    @Override
    public List<Carrier> getCarrierList() {
        return carrierMapper.list();
    }

    @Override @Transactional
    public void updatePieceRule(MasterRule masterRule, List<NewPieceRule> newPieceRuleList, User user){
        Iterator<NewPieceRule> iterator = newPieceRuleList.iterator();
        while (iterator.hasNext()) {
            NewPieceRule newPieceRule = iterator.next();
            String level = String.valueOf(newPieceRule.getRegionId());
            StringBuilder ids = new StringBuilder();
            String toProvince = String.valueOf(newPieceRule.getToProvince());
            String code = toProvince.substring(0, 2);
            List<String> idList = settlementRegionService.getIds(level, code);
            Iterator<String> it = idList.iterator();
            while (it.hasNext()) {
                ids.append(it.next()).append(",");
            }
            if (ids.length()>0){
                ids.deleteCharAt(ids.length() - 1);
                newPieceRule.setRegionId(ids.toString());
            }
            newPieceRule.setUpdateUid(user.getId());
            newRuleMapper.updatePiece(newPieceRule);
        }
        return;
    }

    @Override @Transactional
    public void updateWeightRule(MasterRule masterRule, List<NewWeightRule> newWeightRuleList, User user ) {
        Iterator<NewWeightRule> iterator = newWeightRuleList.iterator();
        while (iterator.hasNext()) {
            NewWeightRule newWeightRule = iterator.next();
            String level = String.valueOf(newWeightRule.getRegionId());
            StringBuilder ids = new StringBuilder();
            String toProvince = String.valueOf(newWeightRule.getToProvince());
            String code = toProvince.substring(0, 2);
            List<String> idList = settlementRegionService.getIds(level, code);
            Iterator<String> it = idList.iterator();
            while (it.hasNext()) {
                ids.append(it.next()).append(",");
            }
            if (ids.length()>0){
                ids.deleteCharAt(ids.length() - 1);
                newWeightRule.setRegionId(ids.toString());
            }
            newWeightRule.setUpdateUid(user.getId());
            newWeightRule.setState(StateEnum.Valid.getState());
            newRuleMapper.updateWeight(newWeightRule);
        }
        return ;
    }

    @Override
    public List<Region> getCityRegionList(String code) {
        return regionCodeMapper.getCityList(code);
    }

    @Override
    public boolean deletePieceRules(String masterRuleId) {
        return newRuleMapper.deletePieceRules(masterRuleId)>0;
    }

    @Override
    public boolean deleteWeightRules(String masterRuleId) {
        return newRuleMapper.deleteWeightRules(masterRuleId)>0;
    }

}
